package com.qa.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qa.common.constant.UserConstant;
import com.qa.common.context.BaseContext;
import com.qa.common.result.Result;
import com.qa.common.utils.StringRedisUtil;
import com.qa.common.utils.TokenUtil;
import com.qa.common.utils.UserUtil;
import com.qa.mapper.UserMapper;
import com.qa.pojo.dto.UserRegisterDTO;
import com.qa.pojo.entity.User;
import com.qa.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Random;

/**
 * @author 徐
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据邮箱获取用户
     *
     * @param mail 邮箱
     * @return 用户User
     */
    @Override
    public User getUserByMail(String mail) {
        return userMapper.getUserByMail(mail);
    }

    @Autowired
    private StringRedisUtil redisCache;

    @Resource
    private JavaMailSender javaMailSender;

    /**
     * 登录
     *
     * @param user 用户
     * @return Result
     */
    @Override
    public Result login(User user) {
        String username = user.getMail();
        String password = user.getPassword();
        // AuthenticationManager authenticate进行用户认证
        User userByMail = userMapper.getUserByMail(username);
        if (!BCrypt.checkpw(password, userByMail.getPassword())) {
            return Result.loginError("登录失败");
        }
        // 使用userid生成token
        Long userId = userByMail.getId();
        String jwt = TokenUtil.genAccessToken(String.valueOf(userId));
        log.info("jwt=" + jwt);
        // authenticate存入redis
        BaseContext.setCurrentId(userId);
        redisCache.setCacheObject("login:" + userId, JSON.toJSONString(userByMail));
        log.info("userid=" + userId + " user=" + userByMail);
        // 把token响应给前端
        HashMap<String, String> map = new HashMap<>();
        map.put("token", jwt);
        // 用户信息
        userByMail.setPassword(null);
        String userJson = JSONObject.toJSONString(userByMail);
        map.put("userInfo", userJson);
        return Result.success(map);
        // return Result.success();
    }

    /**
     * 退出登录
     *
     * @return Result
     */
    @Override
    public Result logout() {
        Long userid = BaseContext.getCurrentId();
        log.info("logout:userid=" + userid);
        redisCache.deleteObject("login:" + userid);
        return Result.success();
    }

    /**
     * 用户注册
     *
     * @param userRegisterDTO 用户注册DTO
     * @return
     */
    @Override
    public Result register(UserRegisterDTO userRegisterDTO) {
        String mail = userRegisterDTO.getMail();
        String password = userRegisterDTO.getPassword();
        String code = userRegisterDTO.getCode();
        String key = UserConstant.REGISTER + mail;
        // 判断验证码
        String correctCode = redisCache.getCacheObject(key);
        log.info("code=" + code + " correctCode=" + correctCode);
        if (!code.equals(correctCode)) {
            return Result.error(UserConstant.CODE_ERROR);
        }
        // 密码加密
        // BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // String encodePassword = passwordEncoder.encode(password);
        String salt = BCrypt.gensalt();
        String encodePassword = BCrypt.hashpw(password, salt);
        // 添加用户
        User user = User.builder()
                .status(UserConstant.USER_STATUS_OK)
                .avatar(UserConstant.DEFAULT_AVATAR)
                .nickname(mail)
                .mail(mail)
                .password(encodePassword)
                .build();
        Integer res = userMapper.addUser(user);
        if (res == 0) {
            return Result.error(UserConstant.USER_REGISTER_FAIL);
        }
        // 删除缓存
        redisCache.deleteObject(key);
        return Result.success();
    }

    /**
     * 发送验证码
     *
     * @return Boolean
     */
    @Override
    public Result sendCode(String mail) {
        // 判断邮箱是否已被注册
        User user = userMapper.getUserByMail(mail);
        if (user != null) {
            return Result.error(UserConstant.MAIL_EXIST);
        }
        Boolean res = sendCodeMail(mail);
        if (!res) {
            return Result.error(UserConstant.CODE_SEND_FAIL);
        }
        return Result.success();
    }

    /**
     * 发送验证码邮件
     *
     * @param to 邮箱
     * @return Boolean
     */
    public Boolean sendCodeMail(String to) {
        SimpleMailMessage message = new SimpleMailMessage();
        // 发送人
        String from = "xlr20031006@163.com";
        message.setFrom(from + "(慧题通)");
        message.setTo(to);
        // 标题
        String subject = "慧题通验证";
        message.setSubject(subject);
        // 生成随机6位验证码
        String code = "";
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            code += (random.nextInt(10));
        }
        String text = "【慧题通】用户，您的验证码是: " + code + "，请在5分钟内使用。本验证码将用于慧题通账号操作，为了您的账号安全，请勿告诉任何人！";
        message.setText(text);
        // 发送邮件
        javaMailSender.send(message);
        String key = UserConstant.REGISTER + to;
        // 存入缓存，设置5分钟过期
        redisCache.setCacheObject(key, code, 5);
        return true;
    }

    /**
     * 修改昵称
     *
     * @param nickname 昵称
     * @return Result
     */
    @Override
    public Result changeNickname(String nickname) {
        User user = User.builder().id(UserUtil.getCurrentUserId()).nickname(nickname).build();
        Integer res = userMapper.updateUser(user);
        if (res == 0) {
            return Result.error(UserConstant.USERINFO_CHANGE_FAIL);
        }
        return Result.success();
    }
}
